﻿using System;
using System.Collections.Generic;
using System.Threading;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
using Mono.Collections.Generic;

namespace Mono.Cecil
{
	// Token: 0x02000099 RID: 153
	internal sealed class MetadataSystem
	{
		// Token: 0x06000593 RID: 1427 RVA: 0x0001F3E4 File Offset: 0x0001D5E4
		private static void InitializePrimitives()
		{
			Dictionary<string, Row<ElementType, bool>> value = new Dictionary<string, Row<ElementType, bool>>(18, StringComparer.Ordinal)
			{
				{
					"Void",
					new Row<ElementType, bool>(ElementType.Void, false)
				},
				{
					"Boolean",
					new Row<ElementType, bool>(ElementType.Boolean, true)
				},
				{
					"Char",
					new Row<ElementType, bool>(ElementType.Char, true)
				},
				{
					"SByte",
					new Row<ElementType, bool>(ElementType.I1, true)
				},
				{
					"Byte",
					new Row<ElementType, bool>(ElementType.U1, true)
				},
				{
					"Int16",
					new Row<ElementType, bool>(ElementType.I2, true)
				},
				{
					"UInt16",
					new Row<ElementType, bool>(ElementType.U2, true)
				},
				{
					"Int32",
					new Row<ElementType, bool>(ElementType.I4, true)
				},
				{
					"UInt32",
					new Row<ElementType, bool>(ElementType.U4, true)
				},
				{
					"Int64",
					new Row<ElementType, bool>(ElementType.I8, true)
				},
				{
					"UInt64",
					new Row<ElementType, bool>(ElementType.U8, true)
				},
				{
					"Single",
					new Row<ElementType, bool>(ElementType.R4, true)
				},
				{
					"Double",
					new Row<ElementType, bool>(ElementType.R8, true)
				},
				{
					"String",
					new Row<ElementType, bool>(ElementType.String, false)
				},
				{
					"TypedReference",
					new Row<ElementType, bool>(ElementType.TypedByRef, false)
				},
				{
					"IntPtr",
					new Row<ElementType, bool>(ElementType.I, true)
				},
				{
					"UIntPtr",
					new Row<ElementType, bool>(ElementType.U, true)
				},
				{
					"Object",
					new Row<ElementType, bool>(ElementType.Object, false)
				}
			};
			Interlocked.CompareExchange<Dictionary<string, Row<ElementType, bool>>>(ref MetadataSystem.primitive_value_types, value, null);
		}

		// Token: 0x06000594 RID: 1428 RVA: 0x0001F56C File Offset: 0x0001D76C
		public static void TryProcessPrimitiveTypeReference(TypeReference type)
		{
			bool flag = type.Namespace != "System";
			if (!flag)
			{
				IMetadataScope scope = type.scope;
				bool flag2 = scope == null || scope.MetadataScopeType > MetadataScopeType.AssemblyNameReference;
				if (!flag2)
				{
					Row<ElementType, bool> row;
					bool flag3 = !MetadataSystem.TryGetPrimitiveData(type, out row);
					if (!flag3)
					{
						type.etype = row.Col1;
						type.IsValueType = row.Col2;
					}
				}
			}
		}

		// Token: 0x06000595 RID: 1429 RVA: 0x0001F5D8 File Offset: 0x0001D7D8
		public static bool TryGetPrimitiveElementType(TypeDefinition type, out ElementType etype)
		{
			etype = ElementType.None;
			bool flag = type.Namespace != "System";
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				Row<ElementType, bool> row;
				bool flag2 = MetadataSystem.TryGetPrimitiveData(type, out row);
				if (flag2)
				{
					etype = row.Col1;
					result = true;
				}
				else
				{
					result = false;
				}
			}
			return result;
		}

		// Token: 0x06000596 RID: 1430 RVA: 0x0001F620 File Offset: 0x0001D820
		private static bool TryGetPrimitiveData(TypeReference type, out Row<ElementType, bool> primitive_data)
		{
			bool flag = MetadataSystem.primitive_value_types == null;
			if (flag)
			{
				MetadataSystem.InitializePrimitives();
			}
			return MetadataSystem.primitive_value_types.TryGetValue(type.Name, out primitive_data);
		}

		// Token: 0x06000597 RID: 1431 RVA: 0x0001F658 File Offset: 0x0001D858
		public void Clear()
		{
			bool flag = this.NestedTypes != null;
			if (flag)
			{
				this.NestedTypes = new Dictionary<uint, Collection<uint>>(0);
			}
			bool flag2 = this.ReverseNestedTypes != null;
			if (flag2)
			{
				this.ReverseNestedTypes = new Dictionary<uint, uint>(0);
			}
			bool flag3 = this.Interfaces != null;
			if (flag3)
			{
				this.Interfaces = new Dictionary<uint, Collection<Row<uint, MetadataToken>>>(0);
			}
			bool flag4 = this.ClassLayouts != null;
			if (flag4)
			{
				this.ClassLayouts = new Dictionary<uint, Row<ushort, uint>>(0);
			}
			bool flag5 = this.FieldLayouts != null;
			if (flag5)
			{
				this.FieldLayouts = new Dictionary<uint, uint>(0);
			}
			bool flag6 = this.FieldRVAs != null;
			if (flag6)
			{
				this.FieldRVAs = new Dictionary<uint, uint>(0);
			}
			bool flag7 = this.FieldMarshals != null;
			if (flag7)
			{
				this.FieldMarshals = new Dictionary<MetadataToken, uint>(0);
			}
			bool flag8 = this.Constants != null;
			if (flag8)
			{
				this.Constants = new Dictionary<MetadataToken, Row<ElementType, uint>>(0);
			}
			bool flag9 = this.Overrides != null;
			if (flag9)
			{
				this.Overrides = new Dictionary<uint, Collection<MetadataToken>>(0);
			}
			bool flag10 = this.CustomAttributes != null;
			if (flag10)
			{
				this.CustomAttributes = new Dictionary<MetadataToken, Range[]>(0);
			}
			bool flag11 = this.SecurityDeclarations != null;
			if (flag11)
			{
				this.SecurityDeclarations = new Dictionary<MetadataToken, Range[]>(0);
			}
			bool flag12 = this.Events != null;
			if (flag12)
			{
				this.Events = new Dictionary<uint, Range>(0);
			}
			bool flag13 = this.Properties != null;
			if (flag13)
			{
				this.Properties = new Dictionary<uint, Range>(0);
			}
			bool flag14 = this.Semantics != null;
			if (flag14)
			{
				this.Semantics = new Dictionary<uint, Row<MethodSemanticsAttributes, MetadataToken>>(0);
			}
			bool flag15 = this.PInvokes != null;
			if (flag15)
			{
				this.PInvokes = new Dictionary<uint, Row<PInvokeAttributes, uint, uint>>(0);
			}
			bool flag16 = this.GenericParameters != null;
			if (flag16)
			{
				this.GenericParameters = new Dictionary<MetadataToken, Range[]>(0);
			}
			bool flag17 = this.GenericConstraints != null;
			if (flag17)
			{
				this.GenericConstraints = new Dictionary<uint, Collection<Row<uint, MetadataToken>>>(0);
			}
			this.Documents = Empty<Document>.Array;
			this.ImportScopes = Empty<ImportDebugInformation>.Array;
			bool flag18 = this.LocalScopes != null;
			if (flag18)
			{
				this.LocalScopes = new Dictionary<uint, Collection<Row<uint, Range, Range, uint, uint, uint>>>(0);
			}
			bool flag19 = this.StateMachineMethods != null;
			if (flag19)
			{
				this.StateMachineMethods = new Dictionary<uint, uint>(0);
			}
		}

		// Token: 0x06000598 RID: 1432 RVA: 0x0001F878 File Offset: 0x0001DA78
		public AssemblyNameReference GetAssemblyNameReference(uint rid)
		{
			bool flag = rid < 1U || (ulong)rid > (ulong)((long)this.AssemblyReferences.Length);
			AssemblyNameReference result;
			if (flag)
			{
				result = null;
			}
			else
			{
				result = this.AssemblyReferences[(int)(rid - 1U)];
			}
			return result;
		}

		// Token: 0x06000599 RID: 1433 RVA: 0x0001F8B0 File Offset: 0x0001DAB0
		public TypeDefinition GetTypeDefinition(uint rid)
		{
			bool flag = rid < 1U || (ulong)rid > (ulong)((long)this.Types.Length);
			TypeDefinition result;
			if (flag)
			{
				result = null;
			}
			else
			{
				result = this.Types[(int)(rid - 1U)];
			}
			return result;
		}

		// Token: 0x0600059A RID: 1434 RVA: 0x00003FB7 File Offset: 0x000021B7
		public void AddTypeDefinition(TypeDefinition type)
		{
			this.Types[(int)(type.token.RID - 1U)] = type;
		}

		// Token: 0x0600059B RID: 1435 RVA: 0x0001F8E8 File Offset: 0x0001DAE8
		public TypeReference GetTypeReference(uint rid)
		{
			bool flag = rid < 1U || (ulong)rid > (ulong)((long)this.TypeReferences.Length);
			TypeReference result;
			if (flag)
			{
				result = null;
			}
			else
			{
				result = this.TypeReferences[(int)(rid - 1U)];
			}
			return result;
		}

		// Token: 0x0600059C RID: 1436 RVA: 0x00003FCF File Offset: 0x000021CF
		public void AddTypeReference(TypeReference type)
		{
			this.TypeReferences[(int)(type.token.RID - 1U)] = type;
		}

		// Token: 0x0600059D RID: 1437 RVA: 0x0001F920 File Offset: 0x0001DB20
		public FieldDefinition GetFieldDefinition(uint rid)
		{
			bool flag = rid < 1U || (ulong)rid > (ulong)((long)this.Fields.Length);
			FieldDefinition result;
			if (flag)
			{
				result = null;
			}
			else
			{
				result = this.Fields[(int)(rid - 1U)];
			}
			return result;
		}

		// Token: 0x0600059E RID: 1438 RVA: 0x00003FE7 File Offset: 0x000021E7
		public void AddFieldDefinition(FieldDefinition field)
		{
			this.Fields[(int)(field.token.RID - 1U)] = field;
		}

		// Token: 0x0600059F RID: 1439 RVA: 0x0001F958 File Offset: 0x0001DB58
		public MethodDefinition GetMethodDefinition(uint rid)
		{
			bool flag = rid < 1U || (ulong)rid > (ulong)((long)this.Methods.Length);
			MethodDefinition result;
			if (flag)
			{
				result = null;
			}
			else
			{
				result = this.Methods[(int)(rid - 1U)];
			}
			return result;
		}

		// Token: 0x060005A0 RID: 1440 RVA: 0x00003FFF File Offset: 0x000021FF
		public void AddMethodDefinition(MethodDefinition method)
		{
			this.Methods[(int)(method.token.RID - 1U)] = method;
		}

		// Token: 0x060005A1 RID: 1441 RVA: 0x0001F990 File Offset: 0x0001DB90
		public MemberReference GetMemberReference(uint rid)
		{
			bool flag = rid < 1U || (ulong)rid > (ulong)((long)this.MemberReferences.Length);
			MemberReference result;
			if (flag)
			{
				result = null;
			}
			else
			{
				result = this.MemberReferences[(int)(rid - 1U)];
			}
			return result;
		}

		// Token: 0x060005A2 RID: 1442 RVA: 0x00004017 File Offset: 0x00002217
		public void AddMemberReference(MemberReference member)
		{
			this.MemberReferences[(int)(member.token.RID - 1U)] = member;
		}

		// Token: 0x060005A3 RID: 1443 RVA: 0x0001F9C8 File Offset: 0x0001DBC8
		public bool TryGetNestedTypeMapping(TypeDefinition type, out Collection<uint> mapping)
		{
			return this.NestedTypes.TryGetValue(type.token.RID, out mapping);
		}

		// Token: 0x060005A4 RID: 1444 RVA: 0x0000402F File Offset: 0x0000222F
		public void SetNestedTypeMapping(uint type_rid, Collection<uint> mapping)
		{
			this.NestedTypes[type_rid] = mapping;
		}

		// Token: 0x060005A5 RID: 1445 RVA: 0x0001F9F4 File Offset: 0x0001DBF4
		public bool TryGetReverseNestedTypeMapping(TypeDefinition type, out uint declaring)
		{
			return this.ReverseNestedTypes.TryGetValue(type.token.RID, out declaring);
		}

		// Token: 0x060005A6 RID: 1446 RVA: 0x00004040 File Offset: 0x00002240
		public void SetReverseNestedTypeMapping(uint nested, uint declaring)
		{
			this.ReverseNestedTypes[nested] = declaring;
		}

		// Token: 0x060005A7 RID: 1447 RVA: 0x0001FA20 File Offset: 0x0001DC20
		public bool TryGetInterfaceMapping(TypeDefinition type, out Collection<Row<uint, MetadataToken>> mapping)
		{
			return this.Interfaces.TryGetValue(type.token.RID, out mapping);
		}

		// Token: 0x060005A8 RID: 1448 RVA: 0x00004051 File Offset: 0x00002251
		public void SetInterfaceMapping(uint type_rid, Collection<Row<uint, MetadataToken>> mapping)
		{
			this.Interfaces[type_rid] = mapping;
		}

		// Token: 0x060005A9 RID: 1449 RVA: 0x00004062 File Offset: 0x00002262
		public void AddPropertiesRange(uint type_rid, Range range)
		{
			this.Properties.Add(type_rid, range);
		}

		// Token: 0x060005AA RID: 1450 RVA: 0x0001FA4C File Offset: 0x0001DC4C
		public bool TryGetPropertiesRange(TypeDefinition type, out Range range)
		{
			return this.Properties.TryGetValue(type.token.RID, out range);
		}

		// Token: 0x060005AB RID: 1451 RVA: 0x00004073 File Offset: 0x00002273
		public void AddEventsRange(uint type_rid, Range range)
		{
			this.Events.Add(type_rid, range);
		}

		// Token: 0x060005AC RID: 1452 RVA: 0x0001FA78 File Offset: 0x0001DC78
		public bool TryGetEventsRange(TypeDefinition type, out Range range)
		{
			return this.Events.TryGetValue(type.token.RID, out range);
		}

		// Token: 0x060005AD RID: 1453 RVA: 0x0001FAA4 File Offset: 0x0001DCA4
		public bool TryGetGenericParameterRanges(IGenericParameterProvider owner, out Range[] ranges)
		{
			return this.GenericParameters.TryGetValue(owner.MetadataToken, out ranges);
		}

		// Token: 0x060005AE RID: 1454 RVA: 0x0001FAC8 File Offset: 0x0001DCC8
		public bool TryGetCustomAttributeRanges(ICustomAttributeProvider owner, out Range[] ranges)
		{
			return this.CustomAttributes.TryGetValue(owner.MetadataToken, out ranges);
		}

		// Token: 0x060005AF RID: 1455 RVA: 0x0001FAEC File Offset: 0x0001DCEC
		public bool TryGetSecurityDeclarationRanges(ISecurityDeclarationProvider owner, out Range[] ranges)
		{
			return this.SecurityDeclarations.TryGetValue(owner.MetadataToken, out ranges);
		}

		// Token: 0x060005B0 RID: 1456 RVA: 0x0001FB10 File Offset: 0x0001DD10
		public bool TryGetGenericConstraintMapping(GenericParameter generic_parameter, out Collection<Row<uint, MetadataToken>> mapping)
		{
			return this.GenericConstraints.TryGetValue(generic_parameter.token.RID, out mapping);
		}

		// Token: 0x060005B1 RID: 1457 RVA: 0x00004084 File Offset: 0x00002284
		public void SetGenericConstraintMapping(uint gp_rid, Collection<Row<uint, MetadataToken>> mapping)
		{
			this.GenericConstraints[gp_rid] = mapping;
		}

		// Token: 0x060005B2 RID: 1458 RVA: 0x0001FB3C File Offset: 0x0001DD3C
		public bool TryGetOverrideMapping(MethodDefinition method, out Collection<MetadataToken> mapping)
		{
			return this.Overrides.TryGetValue(method.token.RID, out mapping);
		}

		// Token: 0x060005B3 RID: 1459 RVA: 0x00004095 File Offset: 0x00002295
		public void SetOverrideMapping(uint rid, Collection<MetadataToken> mapping)
		{
			this.Overrides[rid] = mapping;
		}

		// Token: 0x060005B4 RID: 1460 RVA: 0x0001FB68 File Offset: 0x0001DD68
		public Document GetDocument(uint rid)
		{
			bool flag = rid < 1U || (ulong)rid > (ulong)((long)this.Documents.Length);
			Document result;
			if (flag)
			{
				result = null;
			}
			else
			{
				result = this.Documents[(int)(rid - 1U)];
			}
			return result;
		}

		// Token: 0x060005B5 RID: 1461 RVA: 0x0001FBA0 File Offset: 0x0001DDA0
		public bool TryGetLocalScopes(MethodDefinition method, out Collection<Row<uint, Range, Range, uint, uint, uint>> scopes)
		{
			return this.LocalScopes.TryGetValue(method.MetadataToken.RID, out scopes);
		}

		// Token: 0x060005B6 RID: 1462 RVA: 0x000040A6 File Offset: 0x000022A6
		public void SetLocalScopes(uint method_rid, Collection<Row<uint, Range, Range, uint, uint, uint>> records)
		{
			this.LocalScopes[method_rid] = records;
		}

		// Token: 0x060005B7 RID: 1463 RVA: 0x0001FBCC File Offset: 0x0001DDCC
		public ImportDebugInformation GetImportScope(uint rid)
		{
			bool flag = rid < 1U || (ulong)rid > (ulong)((long)this.ImportScopes.Length);
			ImportDebugInformation result;
			if (flag)
			{
				result = null;
			}
			else
			{
				result = this.ImportScopes[(int)(rid - 1U)];
			}
			return result;
		}

		// Token: 0x060005B8 RID: 1464 RVA: 0x0001FC04 File Offset: 0x0001DE04
		public bool TryGetStateMachineKickOffMethod(MethodDefinition method, out uint rid)
		{
			return this.StateMachineMethods.TryGetValue(method.MetadataToken.RID, out rid);
		}

		// Token: 0x060005B9 RID: 1465 RVA: 0x0001FC30 File Offset: 0x0001DE30
		public TypeDefinition GetFieldDeclaringType(uint field_rid)
		{
			return MetadataSystem.BinaryRangeSearch(this.Types, field_rid, true);
		}

		// Token: 0x060005BA RID: 1466 RVA: 0x0001FC50 File Offset: 0x0001DE50
		public TypeDefinition GetMethodDeclaringType(uint method_rid)
		{
			return MetadataSystem.BinaryRangeSearch(this.Types, method_rid, false);
		}

		// Token: 0x060005BB RID: 1467 RVA: 0x0001FC70 File Offset: 0x0001DE70
		private static TypeDefinition BinaryRangeSearch(TypeDefinition[] types, uint rid, bool field)
		{
			int i = 0;
			int num = types.Length - 1;
			while (i <= num)
			{
				int num2 = i + (num - i) / 2;
				TypeDefinition typeDefinition = types[num2];
				Range range = field ? typeDefinition.fields_range : typeDefinition.methods_range;
				bool flag = rid < range.Start;
				if (flag)
				{
					num = num2 - 1;
				}
				else
				{
					bool flag2 = rid >= range.Start + range.Length;
					if (!flag2)
					{
						return typeDefinition;
					}
					i = num2 + 1;
				}
			}
			return null;
		}

		// Token: 0x04000165 RID: 357
		internal AssemblyNameReference[] AssemblyReferences;

		// Token: 0x04000166 RID: 358
		internal ModuleReference[] ModuleReferences;

		// Token: 0x04000167 RID: 359
		internal TypeDefinition[] Types;

		// Token: 0x04000168 RID: 360
		internal TypeReference[] TypeReferences;

		// Token: 0x04000169 RID: 361
		internal FieldDefinition[] Fields;

		// Token: 0x0400016A RID: 362
		internal MethodDefinition[] Methods;

		// Token: 0x0400016B RID: 363
		internal MemberReference[] MemberReferences;

		// Token: 0x0400016C RID: 364
		internal Dictionary<uint, Collection<uint>> NestedTypes;

		// Token: 0x0400016D RID: 365
		internal Dictionary<uint, uint> ReverseNestedTypes;

		// Token: 0x0400016E RID: 366
		internal Dictionary<uint, Collection<Row<uint, MetadataToken>>> Interfaces;

		// Token: 0x0400016F RID: 367
		internal Dictionary<uint, Row<ushort, uint>> ClassLayouts;

		// Token: 0x04000170 RID: 368
		internal Dictionary<uint, uint> FieldLayouts;

		// Token: 0x04000171 RID: 369
		internal Dictionary<uint, uint> FieldRVAs;

		// Token: 0x04000172 RID: 370
		internal Dictionary<MetadataToken, uint> FieldMarshals;

		// Token: 0x04000173 RID: 371
		internal Dictionary<MetadataToken, Row<ElementType, uint>> Constants;

		// Token: 0x04000174 RID: 372
		internal Dictionary<uint, Collection<MetadataToken>> Overrides;

		// Token: 0x04000175 RID: 373
		internal Dictionary<MetadataToken, Range[]> CustomAttributes;

		// Token: 0x04000176 RID: 374
		internal Dictionary<MetadataToken, Range[]> SecurityDeclarations;

		// Token: 0x04000177 RID: 375
		internal Dictionary<uint, Range> Events;

		// Token: 0x04000178 RID: 376
		internal Dictionary<uint, Range> Properties;

		// Token: 0x04000179 RID: 377
		internal Dictionary<uint, Row<MethodSemanticsAttributes, MetadataToken>> Semantics;

		// Token: 0x0400017A RID: 378
		internal Dictionary<uint, Row<PInvokeAttributes, uint, uint>> PInvokes;

		// Token: 0x0400017B RID: 379
		internal Dictionary<MetadataToken, Range[]> GenericParameters;

		// Token: 0x0400017C RID: 380
		internal Dictionary<uint, Collection<Row<uint, MetadataToken>>> GenericConstraints;

		// Token: 0x0400017D RID: 381
		internal Document[] Documents;

		// Token: 0x0400017E RID: 382
		internal Dictionary<uint, Collection<Row<uint, Range, Range, uint, uint, uint>>> LocalScopes;

		// Token: 0x0400017F RID: 383
		internal ImportDebugInformation[] ImportScopes;

		// Token: 0x04000180 RID: 384
		internal Dictionary<uint, uint> StateMachineMethods;

		// Token: 0x04000181 RID: 385
		internal Dictionary<MetadataToken, Row<Guid, uint, uint>[]> CustomDebugInformations;

		// Token: 0x04000182 RID: 386
		private static Dictionary<string, Row<ElementType, bool>> primitive_value_types;
	}
}
